/**
 * @公司:公约树
 * @位置:苏州
 * @Classname AnimeImageProperty
 * @Date 2022-06-12 下午 12:55
 * @Created by hanWanLu
 * @auther 中文:韩万路
 */


package com.animeJava.mode.animeModel;

import com.animeJava.dao.animeEvent.AnimeEventFinal;
import com.animeJava.dao.animeEvent.AnimeImagRender;
import com.animeJava.dao.animeEvent.AnimeRender;
import com.animeJava.enumData.DirectionEnum;
import com.animeJava.mode.AnimeModel;
import com.animeJava.mode.AnimeRunStart;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 动画图片配置类
 */
public class AnimeImageProperty extends AnimeModel {

    private URI             imageArrayPath  =   null;                 //图片动画的路径
    private int             imageFPS        =   24;                 //图片的每张间隔时间 24毫秒
    private File            files[]         =   null;               //数组图片的流
    private AnimeImagRender update;                 //动画渲染中

    public AnimeImageProperty() {
    }
    public AnimeImageProperty(HashMap<String , Object> params) {
        super(params);
        if(params != null){
            Set<Map.Entry<String, Object>> entries = params.entrySet();
            for (Map.Entry<String, Object> map: entries) {
                if("update".equals(map.getKey()) && map.getValue() != null){
                    this.update = (AnimeImagRender) map.getValue();
                    break;
                }
            }
        }
    }


    public AnimeImageProperty(long delay, boolean autoplay, boolean loop, DirectionEnum direction, AnimeEventFinal begin, AnimeImagRender update, AnimeEventFinal complete) {
        super(delay,autoplay,loop,direction,begin,complete);

        this.update = update;
    }


    @Override
    public long animeFactory(long animeKey , int FPS , AnimeRunStart animeRunStart , AnimeEventFinal begin, AnimeRender update, AnimeEventFinal complete) {
        if(files == null || files.length == 0){
            return 0;
        }
        //是多少次才可开始执行动画
        long delayFrequency = this.getDelay() / FPS;
        //当前动画有多少次的执行中时间        //一共有多少张图片 每张图片需要多长时间

        long durationFrequency = (files.length*imageFPS) / FPS;
        //获取当前的帧数大于延时的时间后的帧数;
        double k = (animeKey - delayFrequency);
        //获取当前是否是来回的状态
        DirectionEnum direction = this.getDirection();
        //获取当前动画执行到了百分之几了
        double thisPath = 0;
        switch (direction){
            case NORMAL:{   //正常
                thisPath = k / durationFrequency;
                break;
            }
            case REVERSE:{  //倒叙
                thisPath = 1 - (k / durationFrequency );
                break;
            }
            case ALTERNATE:{    //来回
                thisPath = (k / durationFrequency >= 0.5? 0.5 - (k / durationFrequency - 0.5):k / durationFrequency )*2;
                break;
            }
        }
        //插入当前时间的百分比
        animeRunStart.setPathPercentage(thisPath);

        //********************动画延时后开始执行****************************//
        //如果当前是延时后的动画 并且动画还未开始
        if(animeKey > delayFrequency && animeRunStart.getRunStart() == 0){
            animeRunStart.setRunStart(1);
            //动画开始执行
            if(this.getBegin() != null){
                //如果run报错则清空当前的动画
                this.getBegin().run("");
            }
            if(begin != null)begin.run("动画开始执行");
        }
        //********************动画延时后执行中****************************//
        //当前的帧数大于延时的时间  并且 小于 延时时间加上 总共时间数 并且动画是在开始之中
        if(animeKey >= delayFrequency && animeKey <= delayFrequency+ durationFrequency && animeKey != 0  ){

            //赋值执行
            if(this.getUpdate() != null   ){
                //当前属于第几张图片
                double v = files.length * thisPath;
                //thisFile
                long thisFile = Math.round(v);
                if(thisFile <= files.length-1 && thisFile >= 0){
                    File file = files[(int) thisFile];
                    try {
                        BufferedImage read = ImageIO.read(file);
                        this.getUpdate().run(thisPath,read);
//                        if(update != null)update.run(thisPath,read);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        //********************动画走完执行****************************//
        //判断当前的时间是否走完  如果走完  则判断是  否循环
        if(animeKey > delayFrequency+durationFrequency +1  && animeRunStart.getRunStart() != -1){

            animeRunStart.setRunStart(-1); //标记-1

            //动画完执行
            if(this.getComplete() != null){
                //如果run报错则清空当前的动画
                this.getComplete().run("动画执行完毕");
            }
            if(complete != null)complete.run("动画执行完毕");
            //并且判断是否循环
            if(this.isLoop()){
                animeKey = 0; //从新执行了
                animeRunStart.setRunStart(0); //标记 0 开始
            }
        }else{
            //每一帧的执行
            //这里控制动画的百分比
            //没走完接着走
            if(animeRunStart.getRunStart() != -1){
                animeKey++;
            }
            //判断当前是否是自动播放如果是自动播放则自动修改为0
            if(animeRunStart.getRunStart() != -1){
                if(this.isLoop()){
                    animeRunStart.setRunStart(0);
                }
                //是手动控制并且不是循环则执行当前
                if(!this.isLoop()){
                    animeKey = (long) ((delayFrequency+durationFrequency)*animeRunStart.getAnimeKeyV2());
                }
            }
        }
        return animeKey;

    }


    public URI getImageArrayPath() {
        return imageArrayPath;
    }

    public void setImageArrayPath(URI imageArrayPath) {
        //获取图片序列
        //判断当前是否是文件夹
        File fileExists = new File(imageArrayPath.getPath());
        if(fileExists.exists()){
            //是文件夹打开文件夹
            File files[] = fileExists.listFiles();
            for (File file:files) {
                String name = file.getName();
                String substring = name.substring(name.length() - 3, name.length());
                if("png".equals(substring) || "PNG".equals(substring) || "jpg".equals(substring) || "JPG".equals(substring)){
                    continue;
                }else{
                    new Exception("此文件夹只能存放图片类型PNG||GPG");
                    return;
                }
            }
            this.files = files;
        }else{
            new Exception("不是图片文件夹");
        }
        this.imageArrayPath = imageArrayPath;

    }

    public int getImageFPS() {
        return imageFPS;
    }

    public void setImageFPS(int imageFPS) {
        this.imageFPS = imageFPS;
    }

    public AnimeImagRender getUpdate() {
        return update;
    }

    public void setUpdate(AnimeImagRender update) {
        this.update = update;
    }
}
